{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Production Sequencing\n", "## Problem Definition\n", "A manufacturer of the metal sector in Stafford manufactures four types of products in sequence on two machines. The Table below provides the necessary technical production details.Taking into account only the data on the production times per product and the maximum daily production capacity of each machine, and taking a maximum daily production of 100 units of each product type, consider and solve a maximal flow model in a graph to determine the maximum number of minutes during which machines 1 and 2 can operate on a production-in-sequence basis given the existing capacity constraints.\n", "\n", "| Machine | Product 1 | Product 2 | Product 3 | Product 4 | Daily Production Capacity (minutes) |\n", "|---------|-----------|-----------|-----------|-----------|-------------------------------------|\n", "| 1 | 2 | 3 | 4 | 2 | 500 |\n", "| 2 | 3 | 2 | 1 | 2 | 380 |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution\n", "This is an example of how graph theory can be used to solve production sequencing problems. In this case, the resource that we want to optimise is machine time. The flow in our graph is going to represent machine time and the unit is going to be minutes. We will have a source node, one node representing the first step of the sequence (machine 1), four nodes representing the different products to be manufactured, another node for the second step of the process (machine 2), and a sink node. The capacity of the edge between the source node and the Machine 1 node is equal to the machine production capacity (500), since it is the total number of minutes that we can use in that machine. The capacities of edges between the machine 1 node and the products nodes are the production times in that machine times the number of units (200, 300, 400, 200), since it is the maximum time that we can invest in each time of product in machine 1. Likewise, the edges between the product nodes and the machine 2 node are 300, 200, 100, and 200, and the capacity of the edge between the machine 2 node and the sink node is 380.\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{('S', 'M1'): Text(0.5,1,'500'),\n", " ('M1', 'P1'): Text(1.5,0.5,'200'),\n", " ('M1', 'P2'): Text(1.5,0.835,'300'),\n", " ('M1', 'P3'): Text(1.5,1.165,'400'),\n", " ('M1', 'P4'): Text(1.5,1.5,'200'),\n", " ('P1', 'M2'): Text(2.5,0.5,'300'),\n", " ('P2', 'M2'): Text(2.5,0.835,'200'),\n", " ('P3', 'M2'): Text(2.5,1.165,'100'),\n", " ('P4', 'M2'): Text(2.5,1.5,'200'),\n", " ('M2', 'T'): Text(3.5,1,'380')}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "import networkx as nx\n", "from IPython.display import display, Markdown\n", "\n", "# Create an empty directed graph structure: \n", "G = nx.DiGraph()\n", "\n", "# Add edges and define two attributes, production and costs:\n", "G.add_edges_from([(\"S\", \"M1\", {\"capacity\": 500, \"production\": 0}),\n", " (\"M1\", \"P1\", {\"capacity\": 200, \"production\": 2}),\n", " (\"M1\", \"P2\", {\"capacity\": 300, \"production\": 3}),\n", " (\"M1\", \"P3\", {\"capacity\": 400, \"production\": 4}),\n", " (\"M1\", \"P4\", {\"capacity\": 200, \"production\": 2}),\n", " (\"P1\", \"M2\", {\"capacity\": 300, \"production\": 3}),\n", " (\"P2\", \"M2\", {\"capacity\": 200, \"production\": 2}),\n", " (\"P3\", \"M2\", {\"capacity\": 100, \"production\": 2}),\n", " (\"P4\", \"M2\", {\"capacity\": 200, \"production\": 2}),\n", " (\"M2\", \"T\", {\"capacity\": 380, \"production\": 0})])\n", "\n", "# Draw the directed graph\n", "pos = {\"S\": (0, 1),\n", " \"M1\": (1, 1),\n", " \"P1\":(2,0),\n", " \"P2\": (2, 0.67),\n", " \"P3\": (2, 1.33),\n", " \"P4\": (2, 2),\n", " \"M2\": (3, 1),\n", " \"T\": (4, 1) \n", " }\n", "\n", "nx.draw(G, pos)\n", "nx.draw_networkx_labels(G, pos)\n", "nx.draw_networkx_nodes(G, pos, node_size=600, node_color='#efefef')\n", "nx.draw_networkx_labels(G, pos, font_weight='bold' )\n", "c_label = nx.get_edge_attributes(G, 'capacity')\n", "nx.draw_networkx_edge_labels(G, pos, edge_labels=c_label)\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "380\n" ] }, { "data": { "text/plain": [ "{'S': {'M1': 380},\n", " 'M1': {'P1': 80, 'P2': 200, 'P3': 100, 'P4': 0},\n", " 'P1': {'M2': 80},\n", " 'P2': {'M2': 200},\n", " 'P3': {'M2': 100},\n", " 'P4': {'M2': 0},\n", " 'M2': {'T': 380},\n", " 'T': {}}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "value, flow = nx.maximum_flow(G, \"S\", \"T\", capacity='capacity' )\n", "print(value)\n", "display(flow)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" }, "pycharm": { "stem_cell": { "cell_type": "raw", "source": [], "metadata": { "collapsed": false } } } }, "nbformat": 4, "nbformat_minor": 2 }